﻿namespace WPForms.Phone.ViewModel
{
    using System;
    using System.Linq;
    using System.Windows.Input;
    using System.Windows.Media;
    using Microsoft.Phone;
    using Microsoft.Phone.Tasks;
    using Microsoft.Practices.Prism.Commands;
    using PhoneUtils.Services;
    using WPForms.Common.Model;
    using WPForms.Phone.DataAccess;

    /// <summary>
    /// View model class for a picture attachments
    /// </summary>
    public class PictureAttachmentViewModel : ElementViewModelBase<PictureAttachment>
    {
        /// <summary>
        /// The currently displayed image.
        /// </summary>
        private ImageSource image;

        /// <summary>
        /// Reference to the data access helper.
        /// </summary>
        private IDataAccess dataAccess;

        /// <summary>
        /// Initializes a new instance of the <see cref="PictureAttachmentViewModel" /> class.
        /// </summary>
        /// <param name="model">The model.</param>
        public PictureAttachmentViewModel(PictureAttachment model)
            : base(model)
        {
            this.dataAccess = ContainerLocator.Current.Resolve<IDataAccess>();
            this.ApplyImage();
            this.ChooseCommand = new DelegateCommand(this.Choose);
            this.TakeCommand = new DelegateCommand(this.Take);
        }

        /// <summary>
        /// Gets the command responsible for selecting a picture from the library
        /// </summary>
        public ICommand ChooseCommand { get; private set; }

        /// <summary>
        /// Gets the command responsible for creating a picture.
        /// </summary>
        public ICommand TakeCommand { get; private set; }

        /// <summary>
        /// Gets the selected image as an image source
        /// </summary>
        public ImageSource Image
        {
            get
            {
                return this.image;
            }

            private set
            {
                this.image = value;
                this.RaisePropertyChanged(() => this.Image);
            }
        }

        /// <summary>
        /// Chooses a new image from the library.
        /// </summary>
        private void Choose()
        {
            var chooser = new PhotoChooserTask();
            chooser.Completed += new EventHandler<PhotoResult>(this.Photo_Completed);
            chooser.Show();
        }

        /// <summary>
        /// Takes a new image.
        /// </summary>
        private void Take()
        {
            var capture = new CameraCaptureTask();
            capture.Completed += new EventHandler<PhotoResult>(this.Photo_Completed);
            capture.Show();
        }

        /// <summary>
        /// Handles the complete events of the photo chooser and taker.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The argument.</param>        
        private void Photo_Completed(object sender, PhotoResult e)
        {
            if (e.TaskResult != TaskResult.OK)
            {
                return;
            }

            var formViewModel = ContainerLocator.Current.Resolve<FormViewModel>();
            byte[] data = null;
            using (var reader = new System.IO.BinaryReader(e.ChosenPhoto))
            {
                data = reader.ReadBytes((int)e.ChosenPhoto.Length);
            }

            WPForms.Phone.DataAccess.Attachment createdAttachment = null;
            this.dataAccess.InTransaction(
                dc =>
                {
                    if (this.Model.AttachmentId.HasValue)
                    {
                        var attachment = dc.Attachments.Single(a => a.Id == this.Model.AttachmentId.Value);
                        attachment.Data = data;
                    }
                    else
                    {
                        createdAttachment = new DataAccess.Attachment()
                        {
                            FormId = formViewModel.CurrentForm.Id,
                            FormSection = formViewModel.CurrentSection.Key,
                            Data = data,
                        };
                        dc.Attachments.InsertOnSubmit(createdAttachment);
                    }
                });
            if (createdAttachment != null)
            {
                this.Model.AttachmentId = createdAttachment.Id;
                formViewModel.CurrentSection.Attachments.Add(new WPForms.Common.Model.Attachment()
                {
                    Data = createdAttachment.Data,
                    Id = createdAttachment.Id,
                });
            }
            else
            {
                formViewModel.CurrentSection.Attachments.Single(a => a.Id == this.Model.AttachmentId).Data = data;
            }

            this.ApplyImage();
        }

        /// <summary>
        /// Sets the currently selected attachment's image as the image source.
        /// </summary>
        private void ApplyImage()
        {
            if (this.Model.AttachmentId.HasValue)
            {
                var data = ContainerLocator.Current.Resolve<FormViewModel>().CurrentSection.Attachments.Single(a => a.Id == this.Model.AttachmentId).Data;
                using (var buffer = new System.IO.MemoryStream(data))
                {
                    this.Image = PictureDecoder.DecodeJpeg(buffer);
                }
            }
        }
    }
}
